package pe.com.bbva.modpre.utileria;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import pe.com.bbva.modpre.utileria.ArbolTablaEvento.ColumnShownChangedEvent;
import pe.com.bbva.modpre.utileria.ArbolTablaEvento.ColumnShownChangedListener;

import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.event.Action.Handler;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.event.ShortcutListener;
import com.vaadin.terminal.Sizeable;
import com.vaadin.terminal.gwt.server.WebBrowser;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Panel;
import com.vaadin.ui.PopupDateField;
import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator;
import com.vaadin.ui.Table.CellStyleGenerator;
import com.vaadin.ui.Table.ColumnReorderEvent;
import com.vaadin.ui.Table.ColumnReorderListener;
import com.vaadin.ui.Table.ColumnResizeEvent;
import com.vaadin.ui.Table.ColumnResizeListener;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

@SuppressWarnings("serial")
public class ArbolTablaFiltro extends CustomComponent {

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private Panel pnlArbolTabla;
	@AutoGenerated
	private VerticalLayout lytArbolTabla;
	@AutoGenerated
	private ArbolTablaEvento arbolTablaEvento;
	@AutoGenerated
	private HorizontalLayout lytFiltro;
	/**
	 * The constructor should first build the main layout, set the
	 * composition root and then do any custom initialization.
	 *
	 * The constructor will not be automatically regenerated by the
	 * visual editor.
	 */	
	SimpleDateFormat fmt = new SimpleDateFormat("dd/MM/yyyy");
	Map<String, Component> mapFiltroId=new HashMap<String, Component>();
	Map<String, Component> mapFiltroHeader=new HashMap<String, Component>();
	Map<String, String> mapFiltroHeaderId=new HashMap<String, String>();
	WebBrowser webBrowser;
	String columna;
	String ancho;
	String colapso;
		
	public ArbolTablaFiltro() {
		buildMainLayout();
		setCompositionRoot(mainLayout);

		postConstruct();
	}
	
	public void postConstruct(){
		pnlArbolTabla.addAction(new ShortcutListener("", KeyCode.ENTER, null) {

			@Override
			public void handleAction(Object sender, Object target) {
				enter();
			}
		});
		
		
		arbolTablaEvento.addListener(new ColumnResizeListener() {
			
			@Override
			public void columnResize(ColumnResizeEvent event) {
				accion();
				int anchoInt=0;
				for (Object propertyId : arbolTablaEvento.getContainerPropertyIds()) {
					if(!arbolTablaEvento.isColumnCollapsed(propertyId) && visibleColumn(propertyId)){
						Component component=mapFiltroId.get(propertyId);
						if (webBrowser!=null && webBrowser.isFirefox()) {
							component.setWidth(arbolTablaEvento.getColumnWidth(propertyId)+12, Sizeable.UNITS_PIXELS);
							anchoInt+=arbolTablaEvento.getColumnWidth(propertyId)+12;
						}else{
							component.setWidth(arbolTablaEvento.getColumnWidth(propertyId)+12, Sizeable.UNITS_PIXELS);
							anchoInt+=arbolTablaEvento.getColumnWidth(propertyId)+12;
						}
						if(component instanceof VerticalLayout){
							VerticalLayout layout=(VerticalLayout)component;
							if(layout.getComponent(0) instanceof PopupDateField){
								PopupDateField field=(PopupDateField)layout.getComponent(0);
								field.setInputPrompt("Desde");
								field=(PopupDateField)layout.getComponent(1);
								field.setInputPrompt("Hasta");
							}
						}
					}
				}
				anchoInt+=30;
				arbolTablaEvento.setWidth(anchoInt, Sizeable.UNITS_PIXELS);
			}
		});
		arbolTablaEvento.addListener(new ColumnReorderListener() {
			
			@Override
			public void columnReorder(ColumnReorderEvent event) {
				accion();
				lytFiltro.removeAllComponents();
				for (String header : arbolTablaEvento.getColumnHeaders()) {
					if(!arbolTablaEvento.isColumnCollapsed(mapFiltroHeaderId.get(header))){
						Component component=mapFiltroHeader.get(header);
						lytFiltro.addComponent(component);
			    		lytFiltro.setComponentAlignment(component, new Alignment(9));
					}
				}
			}
		});
		arbolTablaEvento.addListener(new ColumnShownChangedListener() {
			
			@Override
			public void columnShownChanged(ColumnShownChangedEvent event) {
				accion();
				lytFiltro.removeAllComponents();
				int anchoInt=0;
				for (String header : arbolTablaEvento.getColumnHeaders()) {
					if(!arbolTablaEvento.isColumnCollapsed(mapFiltroHeaderId.get(header))){
						Component component=mapFiltroHeader.get(header);
						lytFiltro.addComponent(component);
			    		lytFiltro.setComponentAlignment(component, new Alignment(9));
						if (webBrowser!=null && webBrowser.isFirefox()) {
							anchoInt+=arbolTablaEvento.getColumnWidth(mapFiltroHeaderId.get(header))+12;
						}else{
							anchoInt+=arbolTablaEvento.getColumnWidth(mapFiltroHeaderId.get(header))+12;
						}
					}
				}
				anchoInt+=30;
				arbolTablaEvento.setWidth(anchoInt, Sizeable.UNITS_PIXELS);
			}
		});
	}
	
	public Object[] columnasColapsables(List<Object> litaIds, String[] cabecera){
		List<Object> columnasReales = new ArrayList<Object>();
		
		int cont=0;
		for (Object object : litaIds) {
			if(!arbolTablaEvento.isColumnCollapsed(object)){
				columnasReales.add(object);
				
			}else{
				cabecera[cont]="";
				
			}
			cont++;
		}
		String[] cabeceraCortada= new String[columnasReales.size()];
		cont=0;
		for (String string : cabecera) {
			if(!(string=="")){
				cabeceraCortada[cont]=string;
				cont++;
			}
			
		}
		return new Object[]{columnasReales,cabeceraCortada};
	}
	
	public void cargarPreferencias(String columna, String ancho, String colapso){
		String columnas[]=StringUtils.split(columna, "|");
        String anchos[]=StringUtils.split(ancho, "|");
        String colapsos[]=StringUtils.split(colapso, "|");
        Object visibleColumns[]=new Object[columnas.length];
        lytFiltro.removeAllComponents();
		int anchoInt=0;
		for (int i = 0; i < columnas.length; i++) {
			visibleColumns[i]=columnas[i];
			if(colapsos[i].equals("1")){
				arbolTablaEvento.setColumnCollapsed(columnas[i], true);
        	}
			if(!arbolTablaEvento.isColumnCollapsed(columnas[i])){
				Component component=mapFiltroId.get(columnas[i]);
				lytFiltro.addComponent(component);
	    		lytFiltro.setComponentAlignment(component, new Alignment(9));
			}
			int anchoColumna=Integer.parseInt(anchos[i]);
        	arbolTablaEvento.setColumnWidth(columnas[i], anchoColumna);
        	Component component=mapFiltroId.get(columnas[i]);
			if (webBrowser!=null && webBrowser.isFirefox()) {
				component.setWidth(arbolTablaEvento.getColumnWidth(columnas[i])+12, Sizeable.UNITS_PIXELS);
				if(!arbolTablaEvento.isColumnCollapsed(columnas[i])){
					anchoInt+=arbolTablaEvento.getColumnWidth(columnas[i])+12;
				}
			}else{
				component.setWidth(arbolTablaEvento.getColumnWidth(columnas[i])+12, Sizeable.UNITS_PIXELS);
				if(!arbolTablaEvento.isColumnCollapsed(columnas[i])){
					anchoInt+=arbolTablaEvento.getColumnWidth(columnas[i])+12;
				}
			}
		}
		arbolTablaEvento.setVisibleColumns(visibleColumns);
		anchoInt+=30;
		arbolTablaEvento.setWidth(anchoInt, Sizeable.UNITS_PIXELS);
	}
	
	public boolean visibleColumn(Object propertyId){
		boolean visible=false;
		for (Object object : arbolTablaEvento.getVisibleColumns()) {
			if(object.equals(propertyId)){
				visible=true;
			}
		}
		return visible;
	}
	
	public void cargarTabla(){
		Container container=arbolTablaEvento.getContainerDataSource();
		int anchoInt=0;
		for(Object propertyId : container.getContainerPropertyIds()){
			int widthComponent=arbolTablaEvento.getColumnWidth(propertyId);
			if(!visibleColumn(propertyId)){
				continue;
			}
			if (webBrowser!=null && webBrowser.isFirefox()) {
				widthComponent=widthComponent+12;
				anchoInt+=widthComponent;
			}else{
				widthComponent=widthComponent+12;
				anchoInt+=widthComponent;
			}
			Class<?> clase=container.getType(propertyId);
			if(clase.equals(Date.class)){
				VerticalLayout layout=new VerticalLayout();
				PopupDateField popupDateField=new PopupDateField();
				popupDateField.setInputPrompt("Desde");
				popupDateField.setWidth("100%");
				popupDateField.setDateFormat(fmt.toPattern());
				popupDateField.setImmediate(true);
				popupDateField.setParseErrorMessage("Formato de fecha no reconocido");
				popupDateField.addListener(new ValueChangeListener() {
					
					@Override
					public void valueChange(ValueChangeEvent event) {
						enter();
					}
				});
				layout.setWidth((widthComponent)+"px");
				layout.addComponent(popupDateField);
				popupDateField=new PopupDateField();
				popupDateField.setInputPrompt("Hasta");
				popupDateField.setWidth("100%");
				popupDateField.setDateFormat(fmt.toPattern());
				popupDateField.setImmediate(true);
				popupDateField.setParseErrorMessage("Formato de fecha no reconocido");
				popupDateField.addListener(new ValueChangeListener() {
					
					@Override
					public void valueChange(ValueChangeEvent event) {
						enter();
					}
				});
				layout.setWidth((widthComponent)+"px");
				layout.addComponent(popupDateField);
	    		lytFiltro.addComponent(layout);
	    		mapFiltroId.put((String)propertyId, layout);
	    		mapFiltroHeader.put(arbolTablaEvento.getColumnHeader(propertyId), layout);
	    		mapFiltroHeaderId.put(arbolTablaEvento.getColumnHeader(propertyId), (String)propertyId);
			}else if(clase.equals(BigDecimal.class)){
				VerticalLayout layout=new VerticalLayout();
				TextField textField=new TextField();
				textField.setInputPrompt("Minimo");
				textField.setWidth("100%");
				layout.setWidth((widthComponent)+"px");
				layout.addComponent(textField);
				textField=new TextField();
				textField.setInputPrompt("Maximo");
				textField.setWidth("100%");
				layout.setWidth((widthComponent)+"px");
				layout.addComponent(textField);
	    		lytFiltro.addComponent(layout);
	    		mapFiltroId.put((String)propertyId, layout);
	    		mapFiltroHeader.put(arbolTablaEvento.getColumnHeader(propertyId), layout);
	    		mapFiltroHeaderId.put(arbolTablaEvento.getColumnHeader(propertyId), (String)propertyId);
			}else{
				TextField textField=new TextField();
				textField.setInputPrompt(arbolTablaEvento.getColumnHeader(propertyId));
	    		textField.setWidth((widthComponent)+"px");
	    		lytFiltro.addComponent(textField);
	    		lytFiltro.setComponentAlignment(textField, new Alignment(9));
	    		mapFiltroId.put((String)propertyId, textField);
	    		mapFiltroHeader.put(arbolTablaEvento.getColumnHeader(propertyId), textField);
	    		mapFiltroHeaderId.put(arbolTablaEvento.getColumnHeader(propertyId), (String)propertyId);
			}
		}
		anchoInt+=30;
		arbolTablaEvento.setWidth(anchoInt, Sizeable.UNITS_PIXELS);
	}
	
	public String[] obtenerPreferencias(){
		String columna="";
		String ancho="";
		String colapso="";
		for (String header : arbolTablaEvento.getColumnHeaders()) {
			String id=mapFiltroHeaderId.get(header);
			columna+=id+"|";
			ancho+=arbolTablaEvento.getColumnWidth(id)+"|";
			if(arbolTablaEvento.isColumnCollapsed(id)){
				colapso+="1|";
			}else{
				colapso+="0|";
			}
		}
		return new String[]{columna,ancho,colapso};
	}
	
	public Map<String, Object> obtenerFiltros(){
		Map<String, Object> map=new HashMap<String, Object>();
		for (String key : mapFiltroId.keySet()) {
			Component component=mapFiltroId.get(key);
			if(component instanceof VerticalLayout){
				VerticalLayout layout=(VerticalLayout)component;
				if(layout.getComponent(0) instanceof PopupDateField){
					PopupDateField field=(PopupDateField)layout.getComponent(0);
					map.put(key+"_1", field.getValue());
					field=(PopupDateField)layout.getComponent(1);
					map.put(key+"_2", field.getValue());
				}else{
					TextField textField=(TextField)layout.getComponent(0);
					map.put(key+"_1", (String)textField.getValue());
					textField=(TextField)layout.getComponent(1);
					map.put(key+"_2", (String)textField.getValue());
				}
			}else{
				TextField textField=(TextField)component;
				map.put(key, (String)textField.getValue());
			}
		}
		return map;
	}
	
	public void accion(){
	}
	
	public void enter(){
	}
	
	public void setContainerDataSource(Container newDataSource){
		String preferencias[]=obtenerPreferencias();
		arbolTablaEvento.setContainerDataSource(newDataSource);
		if(mapFiltroHeaderId.size()!=0){
			cargarPreferencias(preferencias[0], preferencias[1], preferencias[2]);
		}
	}
	
	public Object addItem(Object[] cells, Object itemId){
		return arbolTablaEvento.addItem(cells, itemId);
	}
	
	public boolean removeAllItems(){
		return arbolTablaEvento.removeAllItems();
	}
	
	public void addActionHandler(Handler handler){
		arbolTablaEvento.addActionHandler(handler);
	}
	
	public void setColumnWidth(Object propertyId, int width){
		arbolTablaEvento.setColumnWidth(propertyId, width);
	}
	
	public void setColumnHeader(Object propertyId, String header){
		arbolTablaEvento.setColumnHeader(propertyId, header);
	}
	
	public void setVisibleColumns(Object[] visibleColumns){
		arbolTablaEvento.setVisibleColumns(visibleColumns);
	}
	
	public void setSelectable(boolean selectable){
		arbolTablaEvento.setSelectable(selectable);
	}
	
	public void setNullSelectionAllowed(boolean nullSelectionAllowed){
		arbolTablaEvento.setNullSelectionAllowed(nullSelectionAllowed);
	}
	
	public void setNullSelectionItemId(Object nullSelectionItemId){
		arbolTablaEvento.setNullSelectionItemId(nullSelectionItemId);
	}
	public void setImmediate(boolean immediate){
		arbolTablaEvento.setImmediate(immediate);
	}
	
	public void setColumnReorderingAllowed(boolean columnReorderingAllowed){
		arbolTablaEvento.setColumnReorderingAllowed(columnReorderingAllowed);
	}
	
	public void setColumnCollapsingAllowed(boolean collapsingAllowed){
		arbolTablaEvento.setColumnCollapsingAllowed(collapsingAllowed);
	}
	
	public Collection<?> rootItemIds() {
		return arbolTablaEvento.rootItemIds();
	}

	public void setCollapsed(Object itemId, boolean collapsed) {
		arbolTablaEvento.setCollapsed(itemId, collapsed);
	}
	
	@Override
	public void setStyleName(String style) {
		arbolTablaEvento.setStyleName(style);
	}
	
	public DateFormat getFmt() {
		return fmt;
	}

	public void setFmt(SimpleDateFormat fmt) {
		this.fmt = fmt;
	}

	public WebBrowser getWebBrowser() {
		return webBrowser;
	}

	public void setWebBrowser(WebBrowser webBrowser) {
		this.webBrowser = webBrowser;
	}

	public Item getItem(Object itemId) {
		return arbolTablaEvento.getItem(itemId);
	}
	
	public void addListener(Listener listener){
		arbolTablaEvento.addListener(listener);
	}

	public Object getValue() {
		return arbolTablaEvento.getValue();
	}
	
	public String[] getColumnHeaders() {
		return arbolTablaEvento.getColumnHeaders();
	}
	public Object[] getVisibleColumns(){
		return arbolTablaEvento.getVisibleColumns();
	}
	

	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(false);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("100.0%");
		
		// pnlArbolTabla
		pnlArbolTabla = buildPnlArbolTabla();
		mainLayout.addComponent(pnlArbolTabla);
		mainLayout.setExpandRatio(pnlArbolTabla, 1.0f);
		
		return mainLayout;
	}

	@AutoGenerated
	private Panel buildPnlArbolTabla() {
		// common part: create layout
		pnlArbolTabla = new Panel();
		pnlArbolTabla.setImmediate(false);
		pnlArbolTabla.setWidth("-1px");
		pnlArbolTabla.setHeight("100.0%");
		
		// lytArbolTabla
		lytArbolTabla = buildLytArbolTabla();
		pnlArbolTabla.setContent(lytArbolTabla);
		
		return pnlArbolTabla;
	}

	@AutoGenerated
	private VerticalLayout buildLytArbolTabla() {
		// common part: create layout
		lytArbolTabla = new VerticalLayout();
		lytArbolTabla.setImmediate(false);
		lytArbolTabla.setWidth("-1px");
		lytArbolTabla.setHeight("100.0%");
		lytArbolTabla.setMargin(false);
		
		// lytFiltro
		lytFiltro = new HorizontalLayout();
		lytFiltro.setImmediate(false);
		lytFiltro.setWidth("-1px");
		lytFiltro.setHeight("-1px");
		lytFiltro.setMargin(false);
		lytArbolTabla.addComponent(lytFiltro);
		
		// arbolTablaEvento
		arbolTablaEvento = new ArbolTablaEvento(){

			@Override
			protected String formatPropertyValue(Object rowId, Object colId,
					Property property) {
				if (property.getType() == Date.class && property.getValue()!=null) {
					return fmt.format((Date)property.getValue());
		        }
				return super.formatPropertyValue(rowId, colId, property);
			}
		};
		arbolTablaEvento.setImmediate(false);
		arbolTablaEvento.setWidth("-1px");
		arbolTablaEvento.setHeight("100.0%");
		lytArbolTabla.addComponent(arbolTablaEvento);
		lytArbolTabla.setExpandRatio(arbolTablaEvento, 1.0f);
		
		return lytArbolTabla;
	}

	public Collection<?> getItemIds() {
		return arbolTablaEvento.getItemIds();
	}

	public void addListener(ValueChangeListener listener) {
		arbolTablaEvento.addListener(listener);
	}

	public void addListener(ItemClickListener listener) {
		arbolTablaEvento.addListener(listener);
	}
	
	public void setCellStyleGenerator(CellStyleGenerator cellStyleGenerator){
		arbolTablaEvento.setCellStyleGenerator(cellStyleGenerator);
	}
	
	public void setItemDescriptionGenerator(ItemDescriptionGenerator generator){
		arbolTablaEvento.setItemDescriptionGenerator(generator);
	}
	
}
